'''
进程调度模拟代码

'''
import random

# 定义状态变量
WAIT= 1
RUN = 2
FINISH = 3

# 定义进程数目
process_number = 5

# 进程类PCB
class PCB:
    def __init__(self):
        #进程的名字 创建问题，不可以重复
        self.progress_id = random.randint(1000, 9999)
        #进程的静态优先级
        self.static_priority =random.randint(0,4)
        #进程的动态优先级
        self.dynamic_priority = 255
        #进程的到达时间
        self.come_time = 0
        #进程需要的运行的时间
        self.need_time = random.randint(1,10)
        #已用CPU时间
        self.hold_time = 0
        #进程的状态  W Wait R Run F Finish
        self.status = WAIT

    #打印PCB信息
    def __str__(self):
        return str(self.progress_id) + "\t"+str(self.status) + "\t" + \
               str(self.hold_time) + "\t\t" + str(self.need_time) + "\t\t"+ \
               str(self.come_time)+"\t\t"+str(self.static_priority)+"\t\t"+ \
                        str(self.dynamic_priority)

class process:
    def __init__(self):
        # 未完成的进程队列
        self.queue = []
        # 已完成的进程列表
        self.finish_queue =[]
        # 初始化
        self.init_process()
        # 进行模拟
        self.run_process()

    # python list sort 函数自定义比较属性 选择静动态优先级结合的方法来确定优先级
    def compare_attribute(self,a):
        return a.static_priority + a.dynamic_priority

    # 初始化进程队列
    def init_process(self):
        print("初始化队列进程信息：")
        for i in range(0,process_number):
            # 将构建的每个进程加进队列之中
            self.queue.append(PCB())

        # 对队列进行排序，排序准则为静动态优先级结合的方法来确定优先级
        self.queue.sort(key = self.compare_attribute)
        #打印各个进程的信息
        self.print_process()

    # 静动态优先级结合进程调度算法
    def run_process(self):
        time = 1
        flag = True
        # 之前对队列进行了排序，队列最前面就是优先级最高的进程
        while flag:
        
            for i in range(0,len(self.queue)):
                # 优先级最高的进程
                if i == 0:
                    # 修改进程状态
                    self.queue[0].status = RUN
                    # 进程需要运行的时间减一
                    self.queue[0].need_time -= 1
                    # 进程以运行的时间加一
                    self.queue[0].hold_time += 1
                else:
                    # 其他进程的动态优先级减一
                    self.queue[i].dynamic_priority -= 1
            # 输出当前时间片
            print("时间为"+str(time)+"时的状态为：")
            time += 1
            #打印进程信息
            self.print_process()
            
            # 判断进程是否执行完毕
            if self.queue[0].need_time != 0:
                # 没执行完，重置进程状态为 WAIT
                self.queue[0].status = WAIT
            else:
                # 执行完的进程，将进程状态置为 FINISH ,并从未完成的队列中移除
                self.queue[0].status = FINISH
                # 将已完成的进程加入完成队列之中
                self.finish_queue.append(self.queue.pop(0))
            # 重新对未完成的进程队列进行排序
            self.queue.sort(key = self.compare_attribute)
            
            # 如果未完成的队列为空，则所有队列已完成调度，退出调度
            if len(self.queue) ==0:
                flag =False
        
        # 输出所有进程最后的状态
        print("最终状态为：")
        self.print_process()



    # 打印进程信息
    def print_process(self):
        print("进程号\t状态\t已用时间\t需要时间\t开始时间\t静优先级\t动优先级")
        # 打印未完成队列进程
        for i in range(0,len(self.queue)):
            print(self.queue[i])
        # 打印已完成调度的队列进程
        for j in range(0,len(self.finish_queue)):
            print(self.finish_queue[j])
        print(100*"*")


if __name__ == "__main__":
    test = process()




